package com.bingxue.edu.tools;

import cn.hutool.core.convert.Convert;
import com.bingxue.edu.common.enums.ChangeTypeEnum;
import com.bingxue.edu.common.enums.EnrollmentStatusEnum;
import com.bingxue.edu.common.enums.StudentClassEnum;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.management.education.model.entity.ClassInfo;
import com.bingxue.edu.management.education.model.entity.ClassStudent;
import com.bingxue.edu.management.education.model.entity.EnrollChangeRecord;
import com.bingxue.edu.management.education.model.entity.Enrollment;
import com.bingxue.edu.management.education.model.entity.LessonStudent;
import com.bingxue.edu.management.education.model.entity.Student;
import com.bingxue.edu.management.education.service.ClassInfoService;
import com.bingxue.edu.management.education.service.ClassStudentService;
import com.bingxue.edu.management.education.service.EnrollChangeRecordService;
import com.bingxue.edu.management.education.service.EnrollPermissionService;
import com.bingxue.edu.management.education.service.EnrollRenewalService;
import com.bingxue.edu.management.education.service.EnrollmentService;
import com.bingxue.edu.management.education.service.LessonStudentService;
import com.bingxue.edu.management.education.service.StudentService;
import com.bingxue.edu.management.shop.model.entity.OrderItem;
import com.bingxue.edu.management.shop.model.entity.Refund;
import com.bingxue.edu.management.shop.service.OrderItemService;
import com.bingxue.edu.management.shop.service.RefundService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static com.bingxue.edu.management.education.model.entity.table.ClassInfoTableDef.CLASS_INFO;
import static com.bingxue.edu.management.education.model.entity.table.ClassStudentTableDef.CLASS_STUDENT;
import static com.bingxue.edu.management.education.model.entity.table.EnrollChangeRecordTableDef.ENROLL_CHANGE_RECORD;
import static com.bingxue.edu.management.education.model.entity.table.EnrollmentTableDef.ENROLLMENT;
import static com.bingxue.edu.management.education.model.entity.table.LessonStudentTableDef.LESSON_STUDENT;
import static com.bingxue.edu.management.education.model.entity.table.StudentTableDef.STUDENT;
import static com.bingxue.edu.management.shop.model.entity.table.OrderItemTableDef.ORDER_ITEM;

/**
 * 处理重复缴费导致的订单状态异常
 *
 * @author panbo
 * @since 2024/11/23
 */
@SpringBootTest
public class EnrollmentFixedTool {

    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private EnrollmentService enrollmentService;
    @Autowired
    private EnrollChangeRecordService enrollChangeRecordService;
    @Autowired
    private ClassInfoService classInfoService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private ClassStudentService classStudentService;
    @Autowired
    private EnrollPermissionService enrollPermissionService;
    @Autowired
    private EnrollRenewalService enrollRenewalService;
    @Autowired
    private LessonStudentService lessonStudentService;
    @Autowired
    private RefundService refundService;

//    @Test
//    @Transactional(rollbackFor = Exception.class)
    public void fixed() {
        String name = "庄子洋";
        String phone = "15310150035";
        Student student = studentService.queryChain()
                .where(STUDENT.NAME.eq(name))
                .and(STUDENT.PARENT_PHONE.eq(phone))
                .one();
        ValidationUtils.throwIfNull(student, "学生不存在");
        List<Enrollment> enrollmentList = enrollmentService.queryChain()
                .leftJoin(CLASS_INFO).on(CLASS_INFO.ID.eq(ENROLLMENT.CLASS_ID))
                .where(ENROLLMENT.STUDENT_ID.eq(student.getId()))
                .and(CLASS_INFO.CLASS_YEAR.eq(2025))
                .list();
        for (Enrollment enrollment : enrollmentList) {
            System.out.println("处理enrollment: %s, class: %s%n".formatted(enrollment.getId(), enrollment.getClassId()));
            // 找class student信息
            ClassStudent classStudent = classStudentService.queryChain()
                    .where(CLASS_STUDENT.ENROLLMENT_ID.eq(enrollment.getId()))
                    .and(CLASS_STUDENT.STUDENT_ID.eq(student.getId()))
                        .and(CLASS_STUDENT.STUDENT_CLASS_STATUS.eq(StudentClassEnum.CANCEL_CLASS))
                    .one();
            ValidationUtils.throwIfNull(classStudent, "学员班级信息不存在");

            if (classStudent.getStudentClassStatus() != StudentClassEnum.CANCEL_CLASS) {
                System.out.printf("学员班级信息不为退班： %s，跳过%n", classStudent.getStudentClassStatus());
                continue;
            }
            // 找到退课记录，修改变更类型
            EnrollChangeRecord changeRecord = enrollChangeRecordService.queryChain()
                    .where(ENROLL_CHANGE_RECORD.STUDENT_ID.eq(student.getId()))
                    .and(ENROLL_CHANGE_RECORD.ENROLLMENT_ID.eq(enrollment.getId()))
                    .and(ENROLL_CHANGE_RECORD.CHANGE_TYPE.eq(ChangeTypeEnum.CANCEL_CLASS))
                    .one();
            ValidationUtils.throwIfNull(changeRecord, "退班记录不存在");
            changeRecord.setChangeType(ChangeTypeEnum.CANCEL_LESSON);
            ClassInfo classInfo = classInfoService.getById(enrollment.getClassId());
            List<Integer> lessonIndexList = changeRecord.getOriginalLessonIndexes();
            String lessonIndexListStr = Convert.toStr(lessonIndexList);
            String details = "从[%s]%s，课次为第%s次课，共%d次课".formatted(classInfo.getName(), ChangeTypeEnum.CANCEL_LESSON.getLabel(), lessonIndexListStr, lessonIndexList.size());
            changeRecord.setDetails(details);
            enrollChangeRecordService.updateById(changeRecord);

            // 更新退费记录
            Refund refund = refundService.getById(changeRecord.getBusinessId());
            refund.setChangeType(ChangeTypeEnum.CANCEL_LESSON);
            refundService.updateById(refund);

            // 更新报名信息
            enrollment.setStatus(EnrollmentStatusEnum.NORMAL);
            enrollmentService.updateById(enrollment);

            // 更新班级学员
            classStudent.setStudentClassStatus(StudentClassEnum.NORMAL);
            classStudentService.updateById(classStudent);
            classInfoService.increaseStudentCount(enrollment.getClassId(), 1);

            // 更新课次学员
            OrderItem orderItem = orderItemService.queryChain()
                    .where(ORDER_ITEM.CLASS_ID.eq(enrollment.getClassId()))
                    .and(ORDER_ITEM.STUDENT_ID.eq(enrollment.getStudentId()))
                    .orderBy(ORDER_ITEM.CREATE_TIME.desc())
                    .limit(1)
                    .one();
            System.out.printf("orderItem id: %s%n", orderItem.getId());
            ValidationUtils.throwIfNull(orderItem, "订单项信息不存在");
            List<LessonStudent> lessonStudentList = lessonStudentService.queryChain()
                    .where(LESSON_STUDENT.ENROLLMENT_ID.eq(enrollment.getId()))
                    .and(LESSON_STUDENT.ORDER_ITEM_ID.eq(orderItem.getId()))
                    .and(LESSON_STUDENT.STUDENT_CLASS_STATUS.eq(StudentClassEnum.CANCEL_CLASS))
//                    .and(LESSON.LESSON_INDEX.in(lessonIndexList))
                    .list();
            ValidationUtils.throwIf(lessonStudentList.isEmpty() , "缺少学员课次信息");
            ValidationUtils.throwIf(lessonStudentList.size() != orderItem.getLessonIndexes().size(), "学员课次信息数量不正确");
            // 修改新课次状态
            lessonStudentService.updateChain()
                    .where(LESSON_STUDENT.ENROLLMENT_ID.eq(enrollment.getId()))
                    .and(LESSON_STUDENT.ORDER_ITEM_ID.eq(orderItem.getId()))
                    .and(LESSON_STUDENT.STUDENT_CLASS_STATUS.eq(StudentClassEnum.CANCEL_CLASS))
//                    .and(LESSON.LESSON_INDEX.in(lessonIndexList))
                    .set(LESSON_STUDENT.STUDENT_CLASS_STATUS, StudentClassEnum.NORMAL)
                    .update();
            // 修改旧课次状态
            lessonStudentService.updateChain()
                    .where(LESSON_STUDENT.ENROLLMENT_ID.eq(enrollment.getId()))
                    .and(LESSON_STUDENT.STUDENT_CLASS_STATUS.eq(StudentClassEnum.CANCEL_CLASS))
//                    .and(LESSON.LESSON_INDEX.in(lessonIndexList))
                    .set(LESSON_STUDENT.STUDENT_CLASS_STATUS, StudentClassEnum.CANCEL_LESSON)
                    .update();
//            lessonService.addLessonToStudent(orderItem, enrollment.getStudentId(), classInfo, enrollment.getId(), JoinTypeEnum.ENROLL);
            // 自动更新权限
            enrollPermissionService.updatePermission(enrollment.getStudentId(), classInfo);
            // 更新续报状态
            enrollRenewalService.updateRenewalStatus(enrollment, classInfo);
        }
    }
}
